#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 结构体：游戏状态
struct GameState {
	char board[3][3];      // 棋盘
	char currentPlayer;    // 当前玩家
	int moveCount;         // 步数统计
	char playerX[20];      // X玩家名称
	char playerO[20];      // O玩家名称
};

// 结构体：游戏记录
struct GameRecord {
	char winner[20];       // 获胜者
	int totalMoves;        // 总步数
	char date[20];         // 游戏日期
};

// 函数声明
void initGame(struct GameState *game);
void printBoard(struct GameState *game);
int makeMove(struct GameState *game, int row, int col);
int checkWin(struct GameState *game);
int isBoardFull(struct GameState *game);
void saveGame(struct GameState *game);
int loadGame(struct GameState *game);
void saveRecord(struct GameState *game, char *winner);
void showHistory();

int main() {
	struct GameState game;
	int choice, row, col, gameOver = 0;
	
	printf("=== 井字棋游戏 ===\n");
	
	printf("\n1.新游戏 2.加载游戏 3.查看历史 4.退出\n选择: ");
	scanf("%d", &choice);
	
	if(choice == 1) {
		printf("输入X玩家名字: ");
		scanf("%s", game.playerX);
		printf("输入O玩家名字: ");
		scanf("%s", game.playerO);
		initGame(&game);
	} else if(choice == 2) {
		if(!loadGame(&game)) {
			printf("加载失败，开始新游戏\n");
			printf("输入X玩家名字: ");
			scanf("%s", game.playerX);
			printf("输入O玩家名字: ");
			scanf("%s", game.playerO);
			initGame(&game);
		}
	} else if(choice == 3) {
		showHistory();
		return 0;
	} else {
		return 0;
	}
	
	printf("\n游戏开始!\n");
	
	while(!gameOver) {
		printBoard(&game);
		
		// 显示当前玩家
		char *currentName = (game.currentPlayer == 'X') ? game.playerX : game.playerO;
		printf("\n%s(%c)的回合，输入行和列(1-3): ", currentName, game.currentPlayer);
		scanf("%d %d", &row, &col);
		
		// 转换为数组索引
		row--; col--;
		
		if(row >= 0 && row < 3 && col >= 0 && col < 3) {
			if(makeMove(&game, row, col)) {
				game.moveCount++;
				
				// 检查胜负
				if(checkWin(&game)) {
					printBoard(&game);
					printf("\n %s(%c)获胜!\n", currentName, game.currentPlayer);
					saveRecord(&game, currentName);
					gameOver = 1;
				} else if(isBoardFull(&game)) {
					printBoard(&game);
					printf("\n平局!\n");
					saveRecord(&game, "平局");
					gameOver = 1;
				} else {
					// 切换玩家
					game.currentPlayer = (game.currentPlayer == 'X') ? 'O' : 'X';
					
					// 自动保存游戏
					saveGame(&game);
				}
			} else {
				printf("该位置已被占用!\n");
			}
		} else {
			printf("无效位置!\n");
		}
	}
	
	return 0;
}

void initGame(struct GameState *game) {
	// 初始化棋盘
	for(int i = 0; i < 3; i++) {
		for(int j = 0; j < 3; j++) {
			game->board[i][j] = ' ';
		}
	}
	game->currentPlayer = 'X';
	game->moveCount = 0;
}

void printBoard(struct GameState *game) {
	printf("\n   1   2   3\n");
	for(int i = 0; i < 3; i++) {
		printf("%d ", i+1);
		for(int j = 0; j < 3; j++) {
			printf(" %c ", game->board[i][j]);
			if(j < 2) printf("|");
		}
		if(i < 2) printf("\n  ---|---|---\n");
	}
	printf("\n");
}

int makeMove(struct GameState *game, int row, int col) {
	if(game->board[row][col] == ' ') {
		game->board[row][col] = game->currentPlayer;
		return 1;
	}
	return 0;
}

int checkWin(struct GameState *game) {
	char player = game->currentPlayer;
	
	// 检查行
	for(int i = 0; i < 3; i++) {
		if(game->board[i][0] == player && game->board[i][1] == player && game->board[i][2] == player) {
			return 1;
		}
	}
	
	// 检查列
	for(int i = 0; i < 3; i++) {
		if(game->board[0][i] == player && game->board[1][i] == player && game->board[2][i] == player) {
			return 1;
		}
	}
	
	// 检查对角线
	if(game->board[0][0] == player && game->board[1][1] == player && game->board[2][2] == player) {
		return 1;
	}
	if(game->board[0][2] == player && game->board[1][1] == player && game->board[2][0] == player) {
		return 1;
	}
	
	return 0;
}

int isBoardFull(struct GameState *game) {
	for(int i = 0; i < 3; i++) {
		for(int j = 0; j < 3; j++) {
			if(game->board[i][j] == ' ') {
				return 0;
			}
		}
	}
	return 1;
}

void saveGame(struct GameState *game) {
	FILE *file = fopen("tictactoe_save.dat", "wb");
	if(file) {
		fwrite(game, sizeof(struct GameState), 1, file);
		fclose(file);
	}
}

int loadGame(struct GameState *game) {
	FILE *file = fopen("tictactoe_save.dat", "rb");
	if(file) {
		fread(game, sizeof(struct GameState), 1, file);
		fclose(file);
		printf("游戏加载成功!\n");
		return 1;
	}
	return 0;
}

void saveRecord(struct GameState *game, char *winner) {
	struct GameRecord record;
	FILE *file = fopen("tictactoe_history.dat", "ab");
	
	if(file) {
		strcpy(record.winner, winner);
		record.totalMoves = game->moveCount;
		strcpy(record.date, "2024"); // 简化日期
		
		fwrite(&record, sizeof(struct GameRecord), 1, file);
		fclose(file);
	}
}

void showHistory() {
	struct GameRecord record;
	FILE *file = fopen("tictactoe_history.dat", "rb");
	int count = 1;
	
	printf("\n=== 游戏历史 ===\n");
	printf("序号 获胜者\t步数\t日期\n");
	
	if(file) {
		while(fread(&record, sizeof(struct GameRecord), 1, file)) {
			printf("%2d.  %-8s\t%2d\t%s\n", count, record.winner, record.totalMoves, record.date);
			count++;
		}
		fclose(file);
	} else {
		printf("暂无游戏记录\n");
	}
}